/**
 *
 * Copyright (c) 2009-2012 Envision Mobile Ltd. All rights reserved.
 *
 * Other software and company names mentioned herein or used for developing
 * and/or running the Envision Mobile Ltd's software may be trademarks or trade
 * names of their respective owners.
 *
 * Everything in the source code herein is owned by Envision Mobile Ltd.
 * The recipient of this source code hereby acknowledges and agrees that such
 * information is proprietary to Envision Mobile Ltd. and shall not be used, 
 * disclosed, duplicated, and/or reversed engineered except in accordance
 * with the express written authorization of Envision Mobile Ltd.
 *
 * Module: DrugExtraDTO.java
 * Project: ReyOfLight
 *
 * Description:
 *
 *
 * Developer:   10107896
 * Date:        2012-08-16
 * Version:		1.0
 *
 *
 */
package DTO;

import java.io.ByteArrayInputStream;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;

import org.Consts;
import org.Globals;
import org.Utility;
import org.json.JSONException;
import org.json.JSONObject;

import GameTools.ydPoint;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PathMeasure;
import android.graphics.PorterDuffXfermode;
import android.graphics.Paint.Style;
import android.graphics.Path.Direction;
import android.graphics.Path;
import android.graphics.drawable.Drawable;
import android.os.storage.StorageManager;
import android.util.Log;
import android.graphics.PorterDuff;


/**
 * @author 10107896
 *
 */
public class DrawingActionDTO extends BaseDTO implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -8326353474170336768L;
	public int intUuid;
	
	int drawing_plane_id;
	
	int instuction_number;
	
	public String action;
	
	public Bitmap image;
	
	public Path path;
	public ArrayList<ydPoint> pathPoints;
	
	public String shape;
	
	public String text;
	
	public Paint paint;
	public ydPoint position;
	public ydPoint size;
	public int color;
	public int strokeWidth;
	
	public String hidden="false";
	
	public ydPoint translate=new ydPoint(), pivot=new ydPoint(), scale=new ydPoint();
	public float rads;
		
	
	public DrawingActionDTO(int id, SQLiteDatabase db) { 
		intUuid = id;
		
		Cursor c = null;
		if ("".equalsIgnoreCase(init_statement)) { 

			
			String sql = "SELECT * FROM "+ Consts.TABLE_DRAWING_ACTION 	+ " WHERE " 	+ Consts.COLUMN_ID + " = ? ORDER BY "+ Consts.COLUMN_INSRUCTION_NUMBER + " ASC";
	    	c = db.rawQuery(sql, new String[] {  id+ "" });

		}
		
		if (c != null) { 
			if (c.moveToFirst()) { 
				
				instuction_number=c.getInt(1);
				drawing_plane_id=c.getInt(2);
				action=c.getString(3);
				
				byte[] pic=(c.getBlob(4));   
				if(pic!=null){
				  ByteArrayInputStream imageStream = new ByteArrayInputStream(pic);
				  image= BitmapFactory.decodeStream(imageStream);
				}

				  shape=c.getString(5);
				  text=c.getString(6);
				  String points=c.getString(7);
				  try {
					pathPoints=ydPoint.jsonObjectToArrayList(new JSONObject(points));
					path=Utility.pointsToPath(pathPoints);
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				  
				  color=c.getInt(8);
					strokeWidth=c.getInt(9);
					
					hidden=c.getString(10);
					
					paint=new Paint();
					paint.setStrokeWidth(strokeWidth);
					paint.setColor(color);
					paint.setStyle(Style.STROKE);
					
					if(action.equals(Consts.DRAWING_ACTIONS_TEXT)){
						paint.setStyle(Paint.Style.FILL_AND_STROKE);
						paint.setTextSize(100f);
					}
					
					if(action.equals(Consts.DRAWING_ACTIONS_ERASE)){
						paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
					}
				  
				/*if (c.getDouble(1) > 0) { 
					
					date = new Date((long) c.getDouble(1));
				}
				
				intViral=c.getInt(2);
				intCD4=c.getInt(3);
				strGUid=c.getString(4);*/

				
			} else { 
				Log.d("", "== something happened, could not extract from database");
			}
			if(c != null) {
				c.close();
			}
		} else { 
			Log.d("", "== c was null");
		}
	}
	
	public DrawingActionDTO(String currentAction,int currentColor, int currentStrokeWidth) {
		action=currentAction;
		color=currentColor;
		strokeWidth=currentStrokeWidth;
		
		paint=new Paint();
		paint.setStrokeWidth(strokeWidth);
		paint.setColor(color);
		paint.setStyle(Style.STROKE);
		
		if(action.equals(Consts.DRAWING_ACTIONS_TEXT)){
			paint.setStyle(Paint.Style.FILL_AND_STROKE);
			paint.setTextSize(100f);
		}
		
		if(action.equals(Consts.DRAWING_ACTIONS_ERASE)){
			paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
		}
		
	    paint.setDither(true);                    // set the dither to true
	    paint.setStyle(Paint.Style.STROKE);       // set to STOKE
	    paint.setStrokeJoin(Paint.Join.ROUND);    // set the join to round you want
	    paint.setStrokeCap(Paint.Cap.ROUND);      // set the paint cap to round too
	    paint.setPathEffect(new CornerPathEffect(10) );   // set the path effect when they join.
	    paint.setAntiAlias(true);                         // set anti alias so it smooths
		
		path=new Path();
		pathPoints= new ArrayList<ydPoint>();
		
		position= new ydPoint();
		size= new ydPoint();
	}

	public DrawingActionDTO(String currentAction, String currentShape,
		int currentColor, int currentStrokeWidth) {
		action=currentAction;
		shape=currentShape;
		color=currentColor;
		strokeWidth=currentStrokeWidth;
		
		paint=new Paint();
		paint.setStrokeWidth(strokeWidth);
		paint.setColor(color);
		paint.setStyle(Style.STROKE);
		
		path=new Path();
		pathPoints= new ArrayList<ydPoint>();
	}
	
	public boolean insertIntoDatabase(SQLiteDatabase db) {
		this.db=db;
		try {
			ContentValues values = new ContentValues();
			values.put(Consts.COLUMN_DRAWING_PLANE_ID, drawing_plane_id);
			values.put(Consts.COLUMN_INSRUCTION_NUMBER, instuction_number);
			values.put(Consts.COLUMN_ACTION, action);
			values.put(Consts.COLUMN_SHAPE, shape);
			values.put(Consts.COLUMN_TEXT, text);
			//values.put(Consts.COLUMN_POINTS, Utility.arrayListToJSONARRAY(pathPoints).toString());
			values.put(Consts.COLUMN_POINTS, Utility.pathToJSONARRAY(path).toString());
			values.put(Consts.COLUMN_COLOR, color);
			values.put(Consts.COLUMN_STROKE_WIDTH, strokeWidth);
			values.put(Consts.COLUMN_HIDDEN, "false");
			
			if(image!=null){
			byte[] img=Utility.bitmaptoByteArray(image);
			values.put(Consts.COLUMN_IMAGE, img);
			}

			int r_id = (int) db.insert(Consts.TABLE_DRAWING_ACTION, null, values);

			if (r_id>0){
				id=r_id;
				Log.d("", "== was successfully inserted in db, DRAWING_ACTION");
			}
			else{
				Log.d("", "== unsuccessful in inserting in db, DRAWING_ACTION");
			}
			return r_id>0;
		} catch (Exception e) {
			e.printStackTrace();

			Log.d("", "== unsucessful in inserting in db, DRAWING_ACTION, exception");
		}
		return false;
	}

	public static ArrayList<DrawingActionDTO> getObjectsInDatabase(SQLiteDatabase db) { 
		
		ArrayList<DrawingActionDTO> objects = new ArrayList<DrawingActionDTO>();
		
		try { 
			//SELECT id FROM drug_extra WHERE drug_id=?
			//sqlite3_bind_int(statement, 1, drugUUID)
			String sql = "SELECT _id FROM " + Consts.TABLE_OBJECT;
			Cursor c = db.rawQuery(sql, null);
			
			while (c.moveToNext()) { 
				
				int primaryKey = c.getInt(0);
				DrawingActionDTO obj = new DrawingActionDTO(primaryKey, db);
				objects.add(obj);
			}
			
			if(c != null) {
				c.close();
			}
			
		} catch (Exception e) { 
			e.printStackTrace();
			Log.d("", "== something went wrong, drugExtra, getDrugExtraDB");
		}

		return objects;
	}
	
	public void draw(Canvas canvas){
		
		if(action.equals(Consts.DRAWING_ACTIONS_BRUSH)){
			canvas.drawPath(path, paint);
		}
		
		else if(action.equals(Consts.DRAWING_ACTIONS_Shape)){
/*			if(size!=null){
				path=new Path();
				if(shape.equals(Consts.DRAWING_SHAPE_RECTANGLE)){
					path.addRect(position.x, position.y, position.x+size.x, position.y+size.y, Direction.CW);
					//canvas.drawRect(position.x, position.y, position.x+size.x, position.y+size.y, paint);
				}
				else if(shape.equals(Consts.DRAWING_SHAPE_CIRCLE)){
					path.addCircle(position.x, position.y, Math.abs(size.x), Direction.CW);
					//canvas.drawCircle(position.x, position.y, Math.abs(size.x), paint);
				}
				else if(shape.equals(Consts.DRAWING_SHAPE_LINE)){
					path.moveTo(position.x, position.y);
					path.lineTo(position.x+size.x, position.y+size.y);
					//canvas.drawLine(position.x, position.y, position.x+size.x, position.y+size.y, paint);
				}
				else if(shape.equals(Consts.DRAWING_SHAPE_ARC)){
					//canvas.drawCircle(position.x, position.y, Math.abs(position.x-size.x), paint);
				}*/
				canvas.drawPath(path, paint);
			//}
		}
		
		else if(action.equals(Consts.DRAWING_ACTIONS_TEXT)){
			if(new PathMeasure(path, false).getLength()>3){
				canvas.drawTextOnPath(text, path, 0, 0, paint);
			}
		}
		
		else if(action.equals(Consts.DRAWING_ACTIONS_ERASE)){
			canvas.drawPath(path, paint);
		}
		

		
		
	}
	

	public void draw(Canvas canvas, Matrix matrix) {
		if(path!=null){
			path.transform(matrix);
			draw(canvas);
		}
		
	}

	public void setSize(float x, float y) {
		if(size==null)
			size=new ydPoint();
		
		size.x=x-position.x;
		size.y=y-position.y;
		
	}


	public void deltaMove(ydPoint shift) {
		position.deltaMove(shift);
		
	}

	public void setString(String currentText) {
		text=currentText;
		
	}

	public DrawingActionDTO copy() {
		DrawingActionDTO drawingAction=new DrawingActionDTO(action, shape, color, strokeWidth);
		drawingAction.paint=new Paint(paint);
		drawingAction.path=new Path(path);
		
		return drawingAction;
	}

	public void move(ydPoint shift) {
		position.setCoordinates(shift.x, shift.y);
		
	}

	public void save(int id) {
		drawing_plane_id=id;
		if(action.equals(Consts.DRAWING_ACTIONS_Shape)){
			pathPoints.add(position);
			pathPoints.add(size);
		}

		insertIntoDatabase(Globals.sqlDB);
		
		/*else if(action.equals(Consts.DRAWING_ACTIONS_Shape)){
		}*/
				
	}

	public static void deleteDrawingAction(Integer pk, SQLiteDatabase db) {
		try {
			boolean state = db.delete(Consts.TABLE_DRAWING_ACTION, Consts.COLUMN_DRAWING_PLANE_ID+"=?",
					new String[] { pk + "" }) > 0;

			if (state)
				Log.d("", "== successfully deleted, dose");
			else
				Log.d("", "== problem deleting, dose");
		} catch (SQLException e) {
			Log.e("Database Error: ", e.toString());
			e.printStackTrace();
		}
		
	}
	
	public static ArrayList<DrawingActionDTO> getDrawingActionsInDatabase(SQLiteDatabase db, DrawingPlaneDTO drawingPlane) { 
		
		ArrayList<DrawingActionDTO> drawingActions = new ArrayList<DrawingActionDTO>();
		try { 
			String sql = "SELECT _id FROM " + Consts.TABLE_DRAWING_ACTION+ " WHERE " + Consts.COLUMN_DRAWING_PLANE_ID + " = " + drawingPlane.id + " ORDER BY " + Consts.COLUMN_INSRUCTION_NUMBER + " ASC";
	    	Cursor c = db.rawQuery(sql,null);
	  
	    	
	    	if (c.moveToFirst()) { 
	    		do{
	    			int primaryKey = c.getInt(0);    			
	    			DrawingActionDTO d = new DrawingActionDTO(primaryKey, db);
	    			drawingActions.add(d);
	    		}while(c.moveToNext());
	    	}
	    	if(c != null) {
				c.close();
			}
		} catch (SQLException e) {
			Log.d("", "== does category exist, EXCEPTION");
			Log.e("Database Error: ", e.toString());
			e.printStackTrace();
		}
		
		return drawingActions;
		}


	
}
